/*
 ------------------------------------------------------------------------------
 Copyright (C) 2006-2007 Team Blur.

 This file is part of the Quantum Engine source code.

 The Quantum Engine source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Quantum Engine source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Quantum Engine source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


#include "sv_local.h"


#define RATE_HEADER			48			// Include our header, IP header, and some overhead

/*
 ==================
 SV_WriteGameStateToClient
 ==================
*/
static void SV_WriteGameStateToClient (client_t *client, ByteBuffer *msg){
	// Write the game state
	msg->WriteByte(SVC_GAMESTATE);
	sg->ClientWriteGameState(client->clientNum, msg);
}


/*
 ==================
 SV_WriteSnapshotToClient
 ==================
*/
static void SV_WriteSnapshotToClient (client_t *client, ByteBuffer *msg){

	// Don't send a snapshot if the client isn't active
	if (client->state != CS_ACTIVE)
		return;

	// Write the snapshot
	msg->WriteByte(SVC_SNAPSHOT);
	sg->ClientWriteSnapshot(client->clientNum, msg);
}

/*
 ==================
 SV_SendPacketToClient

 Creates and sends a packet to a client.
 Also called by SV_FinalMessage.
 ==================
*/
void SV_SendPacketToClient (client_t *client, bool force){

	byte	buffer[MAX_MSGLEN];
	ByteBuffer	msg;
	int		index, rateMsec;
	int		i;

	// Initialize the message buffer
	msg.Init(buffer, sizeof(buffer), true);

	// Write a server state if needed
	//SV_WriteServerStateToClient(client, &msg);

	// Write a game state if needed
	SV_WriteGameStateToClient(client, &msg);

	// Write a snapshot if needed
	SV_WriteSnapshotToClient(client, &msg);

	// Write the EOF
	msg.WriteByte(SVC_EOF);

	// Check for overflow
	if (msg.overflowed){
		Com_Printf(S_COLOR_YELLOW "WARNING: msg overflowed for %s\n", client->name);

		msg.ClearWriteState();
	}

	// Deliver the message
	ENetPacket * packet = enet_packet_create (msg.data, msg.getBytesWritten(),0);
	enet_peer_send (client->peer, 0, packet);
	enet_host_flush (svs.server);
}

/*
Sends updated entity states etc to all clients. This is called each frame.
*/
void SV_SendClientPackets (void){

	client_t	*client;
	int			i;

	for (i = 0, client = svs.clients; i < sv_maxClients->integerValue; i++, client++){
		if (client->state == CS_FREE)
			continue;
		if(client->peer==0)
			continue;
		// Create and send a new packet to the client
		SV_SendPacketToClient(client, false);
		enet_host_flush(svs.server);
	}
}
